package threadpoolnio.server;

import threadpoolnio.util.Message;
import threadpoolnio.util.Translate;
import threadpoolnio.util.User;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * ReceiveMessage，服务器接收消息和处理消息的线程类
 * @author
 */
public class ReceiveMessage extends Thread {
    private DatagramSocket serverSocket; //服务器套接字
    private DatagramPacket packet;  //报文
    private List<User> userList=new ArrayList<User>(); //用户列表
    private byte[] data=new byte[8096]; //8K字节数组
    private boolean isContinue=true;
    private int port=9999;

    /**
     * 构造函数
     */
    public ReceiveMessage(int hostPort) {
        try {
            this.port=hostPort;
            //创建UDP数据报套接字,在指定端口侦听
            serverSocket=new DatagramSocket(port);
            System.out.println("聊天服务器开始侦听...");
        } catch (SocketException e) {
            e.printStackTrace();
        }

    }
    @Override
    public void run() {
        while (isContinue) { //循环处理收到的各种消息
            try {
            packet=new DatagramPacket(data,data.length);//构建接收报文
            serverSocket.receive(packet);//接收客户机数据
            //收到的数据转为消息对象
            Message msg=(Message) Translate.ByteToObject(packet.getData());
            if(msg!=null) {
                String userId = msg.getUserId();//当前消息来自用户的id
                String userPwd=msg.getPassword();//当前用户的密码PWD
                if (msg.getType().equalsIgnoreCase("M_LOGIN")) { //是M_LOGIN消息
                    Message backMsg = new Message();

                    //todo:把登录用户存入数据库，mysql,进行验证
                    javaTest01 check=new javaTest01();
                    Map<String,String> userLoginInfo=check.initUI(userId,userPwd);
                    //验证用户名和密码;
                    boolean loginSuccess=check.login(userLoginInfo);
                    if (!loginSuccess) {//登录不成功
                        backMsg.setType("M_FAILURE");
                        byte[] buf = Translate.ObjectToByte(backMsg);
                        DatagramPacket backPacket = new DatagramPacket(buf, buf.length, packet.getAddress(), packet.getPort());//向登录用户发送的报文
                        serverSocket.send(backPacket); //发送
                    } else { //登录成功
                        backMsg.setType("M_SUCCESS");
                        byte[] buf = Translate.ObjectToByte(backMsg);
                        DatagramPacket backPacket = new DatagramPacket(buf, buf.length, packet.getAddress(), packet.getPort());//向登录用户发送的报文
                        serverSocket.send(backPacket); //发送

                        User user = new User();
                        user.setUserId(userId); //用户名
                        user.setPacket(packet); //保存收到的报文
                        userList.add(user); //将新用户加入用户列表

                        //更新服务器聊天室大厅
                        System.out.println(userId + " 登录！\n");
                        //向所有其他在线用户发送M_LOGIN消息，向新登录者发送整个用户列表
                        for (int i = 0; i < userList.size(); i++) { //遍历整个用户列表
                            //向其他在线用户发送M_LOGIN消息
                            if (!userId.equalsIgnoreCase(userList.get(i).getUserId())) {
                                DatagramPacket oldPacket = userList.get(i).getPacket();
                                DatagramPacket newPacket = new DatagramPacket(data, data.length, oldPacket.getAddress(), oldPacket.getPort());//向其他用户发送的报文
                                serverSocket.send(newPacket); //发送
                            }//end if
                            //向当前用户回送M_ACK消息，将第i个用户加入当前用户的用户列表
                            Message other = new Message();
                            other.setUserId(userList.get(i).getUserId());
                            other.setType("M_ACK");
                            byte[] buffer = Translate.ObjectToByte(other);
                            DatagramPacket newPacket = new DatagramPacket(buffer, buffer.length, packet.getAddress(), packet.getPort());
                            serverSocket.send(newPacket);
                        }//end for
                    }//end if
                } else if (msg.getType().equalsIgnoreCase("M_MSG")) { //是M_MSG消息
                    //更新显示
                    System.out.println(userId + " 说：" + msg.getText() + "\n");
                    //转发消息
                    for (int i = 0; i < userList.size(); i++) { //遍历用户
                        DatagramPacket oldPacket = userList.get(i).getPacket();
                        DatagramPacket newPacket = new DatagramPacket(data, data.length, oldPacket.getAddress(), oldPacket.getPort());
                        serverSocket.send(newPacket); //发送
                    }
                } else if (msg.getType().equalsIgnoreCase("M_QUIT")) { //是M_QUIT消息
                    //更新显示
                    System.out.println(userId + " 下线！\n");
                    //删除用户
                    for (int i = 0; i < userList.size(); i++) {
                        if (userList.get(i).getUserId().equals(userId)) {
                            userList.remove(i);
                            break;
                        }
                    }//end for
                    //向其他用户转发下线消息
                    for (int i = 0; i < userList.size(); i++) {
                        DatagramPacket oldPacket = userList.get(i).getPacket();
                        DatagramPacket newPacket = new DatagramPacket(data, data.length, oldPacket.getAddress(), oldPacket.getPort());
                        serverSocket.send(newPacket);
                    }//end for
                }//end if
                else if (msg.getType().equalsIgnoreCase("M_USER")) { //是M_USER消息
                    //更新显示
                    System.out.println(userId + " 发给！"+msg.getTargetId()+"的私有信息");
                    //转发给私聊的人
                    for (int i = 0; i < userList.size(); i++) {
                        //增加发送给私聊用户的判断
                        if(userList.get(i).getUserId().equals(msg.getTargetId())){
                            DatagramPacket oldPacket = userList.get(i).getPacket();
                            DatagramPacket newPacket = new DatagramPacket(data, data.length, oldPacket.getAddress(), oldPacket.getPort());
                            serverSocket.send(newPacket);
                            break;
                        }
                    }//end for
                }

            }
            } catch (IOException | NumberFormatException ex) {  }
        }//end while
    }//end run
    public void close(){
        isContinue=false;
        DatagramSocket clientSocket=null;
        try {
            String msg="quit";
            InetAddress address = InetAddress.getByName("127.0.0.1");
            clientSocket=new DatagramSocket();
            DatagramPacket packet=new DatagramPacket(msg.getBytes(),msg.length(), address,port);
            clientSocket.send(packet); //发送
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (clientSocket != null) {
                clientSocket.close();
            }
            if(serverSocket!=null) {
                serverSocket.close();
                System.out.println("聊天服务器已关闭");
            }
        }

    }
}//end class
